#include<iostream>
#include <string.h>
using namespace std;

class Chararry
{
    public:
    Chararry(const char* str)
    :_capacity(strlen(str)+1)
    ,_data(new char[_capacity]())
    {
        strcpy(_data,str);
    }
    //析构函数 
    ~Chararry()
    {
        //如果_data指针不为空，就释放空间然后置空
        if(_data)
        { 
            delete [] _data;
            _data = nullptr;
        }
    }

    void print() const
    {
        cout << _data << endl;
    }


    //这两个函数是怎么进行重载的呢？
    //函数重载的条件是，函数名相同只要参数列表不同就可以构成重载
    //这两个函数看似参数列表相同其实是不同的，因为this指针的类型不同
    //第一个是 双重const修饰的指针，第二个就是一个this指针，也就是一个指针常量

    //返回值为本身，就用char引用,因为返回值为 char &并且不可以进行修改，所以返回值加const修饰，后面const是不能修改对象的数据成员
    // 这个函数是const对象用来调用的
    const char & operator[](size_t id)const{
        //对下标进行合法性判断
        if(id < _capacity - 1)
        {
            //这两个操作被函数声明中的第二个const限制住了
            // _capacity = 100;
            // _data = new char[10]();
            // _data[id] = 'R';  //还是可以的，上面的const只是对指针指向的地址进行了限制
            //并没有对指向位置的数值进行限制，所以还是可以进行修改的，这种只能人为避免这种操作
            return _data[id];
        }
        else{
            cout << "out of range" << endl;
            //返回一个空字符 & 要绑定左值，不能绑定右值
            //所以要创建一个变量,现在可以绑定了但是这是一个局部变量要对他进行生命周期的延长
            //所以将他定义为static 静态全局变量
            static char nullchar = '\0';
            return nullchar;
        }
    }

    //返回值为本身，就用char引用
    //这个函数是普通对象进行调用的
    char & operator[](size_t id){
        //对下标进行合法性判断
        if(id < _capacity - 1)
            return _data[id];
        else{
            cout << "out of range" << endl;
            //返回一个空字符 & 要绑定左值，不能绑定右值
            //所以要创建一个变量,现在可以绑定了但是这是一个局部变量要对他进行生命周期的延长
            //所以将他定义为static 静态全局变量
            static char nullchar = '\0';
            return nullchar;
        }
    }

    private:
    size_t _capacity;
    char * _data;
};

int main()
{
    Chararry c1("hell0");
    c1[0] ='H'; // c1.operator=(0) = 'H';函数的返回值为一个临时变量不可以对其进行赋值
    c1.print();
    
    //const 对象只能调用const成员函数
    const Chararry ca("world");

    return 0;
}